package com.iwhalecloud.citybrain.flow.platform.manager.application.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSON;

import com.iwhalecloud.citybrain.flow.platform.manager.application.service.CustomEventHandler;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.flowable.engine.common.api.delegate.event.AbstractFlowableEventListener;
import org.flowable.engine.common.api.delegate.event.FlowableEvent;
import org.flowable.engine.common.api.delegate.event.FlowableEventType;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author lilh
 * @date 2019-01-28 15:22
 */
@Component
@Slf4j
public class GlobalFlowableEventListener extends AbstractFlowableEventListener implements InitializingBean {

    @Autowired(required = false)
    private List<CustomEventHandler> eventHandlers = new ArrayList<>();

    private Map<FlowableEventType, List<CustomEventHandler>> typeToHandlerMap = new HashMap<>();

    @SneakyThrows
    @Override
    public void onEvent(FlowableEvent event) {
        List<CustomEventHandler> handlerList = typeToHandlerMap.get(event.getType());
        if (CollectionUtils.isNotEmpty(handlerList)) {
            for (CustomEventHandler handler : handlerList) {
                try {
                    long startTime = System.currentTimeMillis();
                    handler.handle(event);
                    log.info("finish eventListener, handler = {}, timeCost = {}",handler.getClass().getSimpleName(),System.currentTimeMillis()-startTime);
                } catch (Exception ex) {
                    log.error("event listener fail:", ex);
                    throw ex;
                }
            }
        }
    }

    @Override
    public boolean isFailOnException() {
        return true; // 使用自己的异常处理，而不是流程引擎的
    }

    @Override
    public void afterPropertiesSet() {
        for (CustomEventHandler handler : eventHandlers) {
            if (Objects.isNull(typeToHandlerMap.get(handler.getEventType()))) {
                typeToHandlerMap.put(handler.getEventType(), new ArrayList<>());
            }
            typeToHandlerMap.get(handler.getEventType()).add(handler);
        }
    }
}
